home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / atre27.exe / ATREE_27 / LFWIN / WINSYNAN.Y < prev    next >
Text File  |  1992-08-01  |  25KB  |  965 lines

  1. %{
  2. /*****************************************************************************
  3.  ****                                                                     ****
  4.  **** winsynan.y                                                          ****
  5.  ****                                                                     ****
  6.  **** atree release 2.7 for Windows                                       ****
  7.  **** Adaptive Logic Network (ALN) simulation program.                    ****
  8.  **** Copyright (C) A. Dwelly, R. Manderscheid, M. Thomas, W.W. Armstrong ****
  9.  ****               1991, 1992                                            ****
  10.  ****                                                                     ****
  11.  **** License:                                                            ****
  12.  **** A royalty-free license is granted for the use of this software for  ****
  13.  **** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or     ****
  14.  **** modified provided this notice appears in its entirety and unchanged ****
  15.  **** in all derived source programs.  Persons modifying the code are     ****
  16.  **** requested to state the date, the changes made and who made them     ****
  17.  **** in the modification history.                                        ****
  18.  ****                                                                     ****
  19.  **** Patent License:                                                     ****
  20.  **** The use of a digital circuit which transmits a signal indicating    ****
  21.  **** heuristic responsibility is protected by U. S. Patent 3,934,231     ****
  22.  **** and others assigned to Dendronic Decisions Limited of Edmonton,     ****
  23.  **** W. W. Armstrong, President.  A royalty-free license is granted      ****
  24.  **** by the company to use this patent for NON_COMMERCIAL PURPOSES to    ****
  25.  **** adapt logic trees using this program and its modifications.         ****
  26.  ****                                                                     ****
  27.  **** Limited Warranty:                                                   ****
  28.  **** This software is provided "as is" without warranty of any kind,     ****
  29.  **** either expressed or implied, including, but not limited to, the     ****
  30.  **** implied warrantees of merchantability and fitness for a particular  ****
  31.  **** purpose.  The entire risk as to the quality and performance of the  ****
  32.  **** program is with the user.  Neither the authors, nor the             ****
  33.  **** University of Alberta, its officers, agents, servants or employees  ****
  34.  **** shall be liable or responsible in any way for any damage to         ****
  35.  **** property or direct personal or consequential injury of any nature   ****
  36.  **** whatsoever that may be suffered or sustained by any licensee, user  ****
  37.  **** or any other party as a consequence of the use or disposition of    ****
  38.  **** this software.                                                      ****
  39.  **** Modification history:                                               ****
  40.  ****                                                                     ****
  41.  **** 90.02.10 Initial implementation, A.Dwelly                           ****
  42.  **** 91.07.15 Release 2, Rolf Manderscheid                               ****
  43.  **** 91.07.15 Windows Port, M. Thomas                                    ****
  44.  **** 92.04.27 atree v2.5, M. Thomas                                      ****
  45.  **** 92.03.07 Release 2.6, Monroe Thomas                                 ****
  46.  **** 92.01.08 Release 2.7, Monroe Thomas                                 ****
  47.  ****                                                                     ****
  48.  *****************************************************************************/
  49.  
  50. #include "atree.h"
  51. #include "lf.h"
  52.  
  53. extern BOOL train_size_flag;
  54. extern BOOL test_size_flag;
  55. extern BOOL largest_flag;
  56. extern BOOL smallest_flag;
  57. extern BOOL fold_flag;
  58. extern BOOL code_flag;
  59. extern BOOL quant_flag;
  60. extern prog_t prog;
  61.  
  62. FILE *yyin;
  63. int line_no;
  64.  
  65. static BOOL first = TRUE;
  66. static int tuple_ptr;
  67. static int table_ptr;
  68. static int table_size;
  69. extern float far * far *tmp_table;
  70. char szBuffer[120];
  71.  
  72. void
  73. yyerrexit()
  74. {
  75.     int i;
  76.  
  77.     first = TRUE;
  78.  
  79.     if (tmp_table != NULL)
  80.         Free(tmp_table);
  81.  
  82.     for(i = 0; i < prog.total_dimensions; i++)
  83.     {
  84.         if (prog.trainset_sz && prog.train_table[i] != NULL)
  85.             Free(prog.train_table[i]);
  86.  
  87.         if (prog.testset_sz && prog.test_table[i] != NULL)
  88.             Free(prog.test_table[i]);
  89.     }
  90.  
  91.     if (prog.train_table != NULL)
  92.         Free(prog.train_table);
  93.  
  94.     if (prog.test_table != NULL)
  95.         Free(prog.test_table);
  96.  
  97.     if (prog.walk_step != NULL)
  98.         Free(prog.walk_step);
  99.  
  100.     if (prog.code != NULL)
  101.         Free(prog.code);
  102. }
  103.  
  104. %}
  105.  
  106. %token FUNCTION
  107. %token DOMAINS
  108. %token CODOMAINS
  109. %token DIMENSIONS
  110. %token EQUALS
  111. %token INTEGER
  112. %token QUANTIZATION
  113. %token COLON
  114. %token TRAINING
  115. %token SET
  116. /* use _SIZE instaed of SIZE so no conflict with windows.h */
  117. %token _SIZE
  118. %token TEST
  119. %token CODING
  120. %token LARGEST
  121. %token SMALLEST
  122. %token REAL
  123. %token TREE
  124. %token MIN
  125. %token MAX 
  126. %token CORRECT
  127. %token EPOCHS
  128. %token VOTE
  129. %token IDENTIFIER
  130. %token STRING
  131. %token SAVE
  132. %token TO
  133. %token LOAD
  134. %token FROM
  135. %token FOLDED
  136.  
  137. %% /* Program definition */
  138.  
  139. program : function_spec tree_spec
  140.         | tree_spec function_spec
  141.         ;
  142.  
  143. function_spec : FUNCTION dimension codimension
  144.               {
  145.                   int dim;
  146.  
  147.                   prog.total_dimensions = prog.dimensions + prog.codimensions;
  148.  
  149.                   prog.train_table = (float far * far *)
  150.                       Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
  151.                   MEMCHECK(prog.train_table);
  152.  
  153.                   prog.test_table = (float far * far *)
  154.                       Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
  155.                   MEMCHECK(prog.test_table);
  156.  
  157.                   prog.walk_step = (int far *)
  158.                       Malloc((unsigned)sizeof(int) * prog.total_dimensions);
  159.                   MEMCHECK(prog.walk_step);
  160.  
  161.                   prog.code = (LPCODE_T)
  162.                       Malloc((unsigned)sizeof(code_t) * prog.total_dimensions);
  163.                   MEMCHECK(prog.code);
  164.  
  165.                   tmp_table = (float far * far *)
  166.                       Malloc((unsigned)sizeof(float far *) * prog.total_dimensions);
  167.                   MEMCHECK(tmp_table);
  168.  
  169.                   for(dim = 0; dim < prog.total_dimensions; dim++)
  170.                   {
  171.                       prog.test_table[dim] = NULL;
  172.                       prog.train_table[dim] = NULL;
  173.                       tmp_table[dim] = NULL;
  174.                   }
  175.              }
  176.              function_statements
  177.  
  178. dimension : DOMAINS DIMENSIONS EQUALS INTEGER
  179.           {
  180.               prog.dimensions = $4.i;
  181.               if (prog.dimensions < 1)
  182.               {
  183.                   wsprintf(szBuffer, "number of domain dimensions must be at least 1, line %d.\n", line_no);
  184.                   MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  185.                   yyerrexit();
  186.                   return(1);
  187.               }
  188.           }
  189.  
  190. codimension : /* empty */
  191.             {
  192.                 prog.codimensions = 1;
  193.             }
  194.             | CODOMAINS DIMENSIONS EQUALS INTEGER
  195.             {
  196.                 prog.codimensions = $4.i;
  197.                 if (prog.codimensions < 1)
  198.                 {
  199.                     wsprintf(szBuffer, "number of codomain dimensions must be at least 1, line %d.\n", line_no);
  200.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  201.                     yyerrexit();
  202.                     return(1);
  203.                 }
  204.             }
  205.             ;
  206.  
  207. function_statements : function_statement
  208.                     | function_statements function_statement
  209.                     ;
  210.  
  211. function_statement : quantization
  212.                    | coding
  213.                    | coding_io
  214.                    | train_table_size
  215.                    | train_table
  216.                    | test_table_size
  217.                    | test_table
  218.                    | largest
  219.                    | smallest
  220.                    ;
  221.  
  222. quantization : QUANTIZATION EQUALS
  223.              {
  224.                  tuple_ptr = 0;
  225.                  quant_flag = TRUE;
  226.                  if (prog.load_code)
  227.                  {
  228.                      wsprintf(szBuffer,
  229.                         "warning: coding(s) will be read from file '%s',\n\tquantization statement ignored, line %d.\n",
  230.                         (LPSTR)prog.load_code,line_no);
  231.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  232.                  }
  233.              }
  234.              quant_list
  235.              {
  236.                  if (tuple_ptr > prog.total_dimensions)
  237.                  {
  238.                      prog.error = TRUE;
  239.                      wsprintf(szBuffer, "too many elements in quantization list on line %d.\n", line_no);
  240.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  241.                  }
  242.                  if (tuple_ptr < prog.total_dimensions)
  243.                  {
  244.                      prog.error = TRUE;
  245.                      wsprintf(szBuffer, "too few elements in quantization list on line %d.\n", line_no);
  246.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  247.                  }
  248.             }
  249.             ;
  250.  
  251. quant_list : INTEGER
  252.            {
  253.                if (tuple_ptr < prog.total_dimensions)
  254.                {
  255.                    prog.code[tuple_ptr].vector_count = $1.i;
  256.                    if ($1.i < 2)
  257.                    {
  258.                        prog.error = TRUE;
  259.                        wsprintf(szBuffer, "must have at least 2 quantization levels, column %d.\n", tuple_ptr + 1);
  260.                        MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  261.                    }
  262.                }
  263.                tuple_ptr++;
  264.            }
  265.            | quant_list  INTEGER
  266.            {
  267.                if (tuple_ptr < prog.total_dimensions)
  268.                {
  269.                    prog.code[tuple_ptr].vector_count = $2.i;
  270.                    if ($2.i < 2)
  271.                    {
  272.                        prog.error = TRUE;
  273.                        wsprintf(szBuffer, "must have at least 2 quantization levels, column %d.\n", tuple_ptr + 1);
  274.                        MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  275.                    }
  276.                }
  277.                tuple_ptr++;
  278.            }
  279.            ;
  280.  
  281. coding : CODING EQUALS
  282.        {
  283.            tuple_ptr = 0;
  284.            code_flag = TRUE;
  285.            if (prog.load_code)
  286.            {
  287.                wsprintf(szBuffer,
  288.                     "warning: coding(s) will be read from file '%s',\n\tcoding statement ignored, line %d.\n",
  289.                          (LPSTR)prog.load_code, line_no);
  290.                MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  291.            }
  292.        }
  293.        code_list
  294.        {
  295.            if (tuple_ptr > prog.total_dimensions)
  296.            {
  297.                prog.error = TRUE;
  298.                wsprintf(szBuffer, "too many elements in coding list on line %d.\n", line_no);
  299.                MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  300.            }
  301.            if (tuple_ptr < prog.total_dimensions)
  302.            {
  303.                prog.error = TRUE;
  304.                wsprintf(szBuffer, "too few elements in coding list on line %d.\n", line_no);
  305.                MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  306.            }
  307.        }
  308.        ;
  309.  
  310. code_list : INTEGER COLON INTEGER
  311.           {
  312.               if (tuple_ptr < prog.total_dimensions)
  313.               {
  314.                   prog.code[tuple_ptr].width = $1.i;
  315.                   prog.walk_step[tuple_ptr] = $3.i;
  316.                   if ($1.i < 1)
  317.                   {
  318.                       prog.error = TRUE;
  319.                       wsprintf(szBuffer, "coding width must be at least 1, column %d.\n", tuple_ptr + 1);
  320.                       MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  321.                   }
  322.                   if ($3.i < 1)
  323.                   {
  324.                       prog.error = TRUE;
  325.                       wsprintf(szBuffer, "coding distance must be at least 1, column %d.\n", tuple_ptr + 1);
  326.                       MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  327.                   }
  328.                   if ($3.i > $1.i)
  329.                   {
  330.                       prog.error = TRUE;
  331.                       wsprintf(szBuffer, "coding distance must not be greater than coding width, column %d.\n", tuple_ptr + 1);
  332.                       MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  333.                   }
  334.               }
  335.               tuple_ptr++;
  336.           }
  337.           | code_list INTEGER COLON INTEGER
  338.           {
  339.               if (tuple_ptr < prog.total_dimensions)
  340.               {
  341.                   prog.code[tuple_ptr].width = $2.i;
  342.                   prog.walk_step[tuple_ptr] = $4.i;
  343.               }
  344.               tuple_ptr++;
  345.           }
  346.           ;
  347.  
  348. coding_io : SAVE CODING TO STRING
  349.           {
  350.               prog.save_code = $4.s;
  351.           }
  352.           | LOAD CODING FROM STRING
  353.           {
  354.               prog.load_code = $4.s;
  355.               if (code_flag || quant_flag)
  356.               {
  357.                   wsprintf(szBuffer,
  358.                         "warning: coding(s) will be read from file '%s',\n\tcoding and quantization statements ignored.\n",
  359.                          (LPSTR)prog.load_code);
  360.                   MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  361.               }
  362.           }
  363.           ;
  364.  
  365. train_table_size : TRAINING SET _SIZE EQUALS INTEGER
  366.             {
  367.                 prog.trainset_sz = $5.i;
  368.                 train_size_flag = TRUE;
  369.             }
  370.             ;
  371.  
  372. train_table : TRAINING SET EQUALS
  373.             {
  374.                 if (!train_size_flag)
  375.                 {
  376.                     wsprintf(szBuffer, "training set defined before size.\n");
  377.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  378.                     yyerrexit();
  379.                     return(1);
  380.                 }
  381.                 else
  382.                 {
  383.                     int dim;
  384.  
  385.                     tuple_ptr = 0;
  386.                     table_ptr = 0;
  387.                     table_size = prog.trainset_sz;
  388.  
  389.                     if (table_size > 0)
  390.                     {
  391.                         for (dim = 0; dim < prog.total_dimensions; dim++)
  392.                         {
  393.                             tmp_table[dim] = (float far *)
  394.                                 Malloc((unsigned) sizeof(float) * table_size);
  395.                             MEMCHECK(tmp_table[dim]);
  396.                         }
  397.                     }
  398.                 }
  399.             }
  400.             table
  401.             {
  402.                 int dim;
  403.  
  404.                 if (tuple_ptr < prog.trainset_sz)
  405.                 {
  406.                     prog.error = TRUE;
  407.                     wsprintf(szBuffer,"too few elements in training set.\n");
  408.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  409.                 }
  410.                 else if (tuple_ptr > prog.trainset_sz || table_ptr != 0)
  411.                 {
  412.                     wsprintf(szBuffer, "warning: extra elements in training set ignored.\n");
  413.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  414.                 }
  415.                 for (dim = 0; dim < prog.total_dimensions; dim++)
  416.                 {
  417.                     prog.train_table[dim] = (prog.trainset_sz ? tmp_table[dim] : NULL);
  418.                 }
  419.             }
  420.  
  421. test_table_size : TEST SET _SIZE EQUALS INTEGER
  422.             {
  423.                 prog.testset_sz = $5.i;
  424.                 test_size_flag = TRUE;
  425.             }
  426.             ;
  427.  
  428. test_table  : TEST SET EQUALS
  429.             {
  430.                 if (!test_size_flag)
  431.                 {
  432.                     wsprintf(szBuffer, "test set defined before size.\n");
  433.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  434.                     yyerrexit();
  435.                     return(1);
  436.                 }
  437.                 else
  438.                 {
  439.                     int dim;
  440.  
  441.                     tuple_ptr = 0;
  442.                     table_ptr = 0;
  443.                     table_size = prog.testset_sz;
  444.  
  445.                     if (table_size > 0)
  446.                     {
  447.                         for (dim = 0; dim < prog.total_dimensions; dim++)
  448.                         {
  449.                             tmp_table[dim] = (float far *)
  450.                                 Malloc((unsigned)sizeof(float) * table_size);
  451.                             MEMCHECK(tmp_table[dim]);
  452.                         }
  453.                     }
  454.                 }
  455.             }
  456.             table
  457.             {
  458.                 int dim;
  459.  
  460.                 if (tuple_ptr < prog.testset_sz)
  461.                 {
  462.                     prog.error = TRUE;
  463.                     wsprintf(szBuffer, "too few elements in test set.\n");
  464.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  465.                 }
  466.                 else if (tuple_ptr > prog.testset_sz || table_ptr != 0)
  467.                 {
  468.                     wsprintf(szBuffer, "warning: extra elements in test set ignored.\n");
  469.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  470.                 }
  471.                 for (dim = 0; dim < prog.total_dimensions; dim++)
  472.                 {
  473.                     prog.test_table[dim] = (prog.testset_sz ? tmp_table[dim] : NULL);
  474.                 }
  475.             }
  476.             ;
  477.  
  478. table : num
  479.       {
  480.           if (tuple_ptr < table_size)
  481.           {
  482.               tmp_table[table_ptr][tuple_ptr] = $1.f;
  483.           }
  484.           table_ptr++;
  485.           if (table_ptr == prog.total_dimensions)
  486.           {
  487.               table_ptr = 0;
  488.               tuple_ptr++;
  489.           }
  490.       }
  491.       | table num
  492.       {
  493.           if (tuple_ptr < table_size)
  494.           {
  495.               tmp_table[table_ptr][tuple_ptr] = $2.f;
  496.           }
  497.           table_ptr++;
  498.           if (table_ptr == prog.total_dimensions)
  499.           {
  500.               table_ptr = 0;
  501.               tuple_ptr++;
  502.           }
  503.       }
  504.       ;
  505.  
  506. num : REAL
  507.     | INTEGER
  508.     {
  509.         $$.f = (float) $1.i;
  510.     }
  511.     ;
  512.  
  513. largest : LARGEST EQUALS
  514.              {
  515.                  tuple_ptr = 0;
  516.                  largest_flag = TRUE;
  517.              }
  518.              largest_list
  519.              {
  520.                  if (tuple_ptr > prog.total_dimensions)
  521.                  {
  522.                      prog.error = TRUE;
  523.                      wsprintf(szBuffer, "too many elements in largest list on line %d.\n", line_no);
  524.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  525.                  }
  526.                  if (tuple_ptr < prog.total_dimensions)
  527.                  {
  528.                      prog.error = TRUE;
  529.                      wsprintf(szBuffer, "too few elements in largest list on line %d.\n", line_no);
  530.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  531.                  }
  532.              }
  533.              ;
  534.  
  535. largest_list : num
  536.              {
  537.                  if (tuple_ptr < prog.total_dimensions)
  538.                  {
  539.                      prog.code[tuple_ptr].high = $1.f;
  540.                  }
  541.                  tuple_ptr++;
  542.              }
  543.              | largest_list num
  544.              {
  545.                  if (tuple_ptr < prog.total_dimensions)
  546.                  {
  547.                      prog.code[tuple_ptr].high = $2.f;
  548.                  }
  549.                  tuple_ptr++;
  550.              }
  551.              ;
  552.  
  553. smallest : SMALLEST EQUALS
  554.              {
  555.                  tuple_ptr = 0;
  556.                  smallest_flag = TRUE;
  557.              }
  558.              smallest_list 
  559.              {
  560.                  if (tuple_ptr > prog.total_dimensions)
  561.                  {
  562.                      prog.error = TRUE;
  563.                      wsprintf(szBuffer, "too many elements in smallest list on line %d.\n", line_no);
  564.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  565.                  }
  566.                  else if (tuple_ptr < prog.total_dimensions)
  567.                  {
  568.                      prog.error = TRUE;
  569.                      wsprintf(szBuffer, "too few elements in smallest list on line %d.\n", line_no);
  570.                      MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  571.                  }
  572.              }
  573.              ;
  574.  
  575. smallest_list : num
  576.              {
  577.                  if (tuple_ptr < prog.total_dimensions)
  578.                  {
  579.                      prog.code[tuple_ptr].low = $1.f;
  580.                  }
  581.                  tuple_ptr++;
  582.              }
  583.              | smallest_list num
  584.              {
  585.                  if (tuple_ptr < prog.total_dimensions)
  586.                  {
  587.                      prog.code[tuple_ptr].low = $2.f;
  588.                  }
  589.                  tuple_ptr++;
  590.              }
  591.  
  592. tree_spec : TREE tree_statements
  593.  
  594. tree_statements : tree_statement
  595.                 | tree_statements tree_statement
  596.  
  597. tree_statement : tree_size
  598.                | tree_io
  599.                | min_correct
  600.                | max_epochs
  601.                | vote_no
  602.                ;
  603.  
  604. tree_size : _SIZE EQUALS INTEGER
  605.           {
  606.               if (prog.load_tree)
  607.               {
  608.                   wsprintf(szBuffer,
  609.                           "warning: tree(s) will be read from file '%s',\n\ttree size statement ignored, line %d.\n",
  610.                            (LPSTR)prog.load_tree, line_no);
  611.                   MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  612.               }
  613.               else if ($3.i < 1)
  614.               {
  615.                   wsprintf(szBuffer, "lf: tree size too small, line %d.\n",
  616.                                  line_no);
  617.                   MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  618.                   prog.error++;
  619.               }
  620.               else
  621.               {
  622.                   prog.tree_sz = $3.i;
  623.               }
  624.           }
  625.           ;
  626.  
  627. tree_io : SAVE TREE TO STRING
  628.         {
  629.             prog.save_tree = $4.s;
  630.             fold_flag = FALSE;
  631.         }
  632.         | SAVE FOLDED TREE TO STRING
  633.         {
  634.             prog.save_tree = $5.s;
  635.             fold_flag = TRUE;
  636.         }
  637.         | LOAD TREE FROM STRING
  638.         {
  639.             prog.load_tree = $4.s;
  640.             if (prog.tree_sz > 0)
  641.             {
  642.                 wsprintf(szBuffer,
  643.                           "lf: warning: tree(s) will be read from file '%s',\n\ttree size statement ignored, line %d.\n",
  644.                           (LPSTR)prog.load_tree,line_no);
  645.                 MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  646.             }
  647.         }
  648.         ;
  649.  
  650.  
  651. min_correct : MIN CORRECT EQUALS INTEGER
  652.             {
  653.                 prog.min_correct = $4.i;
  654.             }
  655.             ;
  656.  
  657. max_epochs : MAX EPOCHS EQUALS INTEGER
  658.            {
  659.                prog.max_epochs = $4.i;
  660.            }
  661.            ;
  662.  
  663. vote_no : VOTE EQUALS INTEGER
  664.         {
  665.             if ($3.i % 2 != 1)
  666.             {
  667.                 wsprintf(szBuffer,
  668.                                "vote number must be odd, line %d.\n",
  669.                                line_no);
  670.                 MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  671.                 yyerrexit();
  672.                 return(1);
  673.             }
  674.             prog.vote = $3.i;
  675.         }
  676.         ;
  677. %%
  678.  
  679. yyerror(description)
  680. char *description;
  681. {
  682.     wsprintf(szBuffer, "%s, line %d.\n", (LPSTR)description, line_no);
  683.     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  684.     prog.error = TRUE;
  685.     yyerrexit();    /* prepare for exit */
  686.     return(0);
  687. }
  688.  
  689.  
  690. /* Lexical states */
  691.  
  692. #define LEX_START 0
  693. #define LEX_INT 1
  694. #define LEX_DEC 2
  695. #define LEX_IDENT 3
  696. #define LEX_PUNCT 4
  697. #define LEX_COMMENT 5
  698. #define LEX_STRING 6
  699. #define LEX_STOP 1000
  700.  
  701. #define ISCOMMENT(c) ((c) == '#')
  702. #define MAX_LEN_BUF 1000
  703.  
  704. static char yytext[MAX_LEN_BUF];
  705. static int lexstate;
  706. static int nextchar;
  707.  
  708.  
  709. static void
  710. lexinit()
  711.  
  712. {
  713.     lexstate = LEX_START;
  714.     nextchar = getc(yyin);
  715. }
  716.  
  717. isextdigit(c)
  718.  
  719. char c;
  720.  
  721. {
  722.     return((c == 'e') || (c == 'E') || (c == '+') || (c == '-') || isdigit(c));
  723. }
  724.  
  725. iswhite(c)
  726.  
  727. char c;
  728.  
  729. {
  730.     if (c == '\n')
  731.     {
  732.         line_no++;
  733.         return(TRUE);
  734.     }
  735.     else
  736.     {
  737.         return((c == 0) || (c == ' ') || (c == '\t'));
  738.     }
  739. }
  740.  
  741. static int
  742. gettoken(str)
  743.  
  744. char *str;
  745.  
  746. {
  747.  
  748.     int i;
  749.     int outcode;
  750.  
  751.     static struct tok
  752.     {
  753.         char *token;
  754.         int code;
  755.     } toktab[] =
  756.     {
  757.         "function"    , FUNCTION,
  758.         "dimension"   , DIMENSIONS,
  759.         "dimensions"  , DIMENSIONS,
  760.         "="           , EQUALS,
  761.         "quantization", QUANTIZATION,
  762.         ":"           , COLON,
  763.         "coding"      , CODING,
  764.         "training"    , TRAINING,
  765.         "set"         , SET,
  766.         "size"        , _SIZE,
  767.         "test"        , TEST,
  768.         "tree"        , TREE,
  769.         "minimum"     , MIN,
  770.         "min"         , MIN,
  771.         "maximum"     , MAX,
  772.         "max"         , MAX,
  773.         "correct"     , CORRECT,
  774.         "epochs"      , EPOCHS,
  775.         "largest"     , LARGEST,
  776.         "smallest"    , SMALLEST,
  777.         "domain"      , DOMAINS,
  778.         "codomain"    , CODOMAINS,
  779.         "vote"        , VOTE,
  780.         "save"        , SAVE,
  781.         "to"          , TO,
  782.         "load"        , LOAD,
  783.         "from"        , FROM,
  784.         "folded"      , FOLDED,
  785.         NULL          ,0
  786.     };
  787.  
  788.     outcode = IDENTIFIER;
  789.  
  790.     for (i = 0; toktab[i].token != NULL; i++)
  791.     {
  792.         if (strcmp(str,toktab[i].token) == 0)
  793.         {
  794.             outcode = toktab[i].code;
  795.             break;
  796.         }
  797.     }
  798.  
  799.     return(outcode);
  800. }
  801.  
  802. static int
  803. yylex()
  804.  
  805. {
  806.     int bufptr;
  807.     BOOL found_token;
  808.     int token;
  809.  
  810.     found_token = FALSE;
  811.     bufptr = 0;
  812.  
  813.     if (first)
  814.     {
  815.         first = FALSE;
  816.         lexinit();
  817.     }
  818.  
  819.     while (!found_token)
  820.     {
  821.         switch (lexstate)
  822.         {
  823.             case LEX_START:
  824.                 while (iswhite(nextchar))
  825.                 {
  826.                      nextchar = getc(yyin);
  827.                 }
  828.  
  829.                 if (ISCOMMENT(nextchar))
  830.                 {
  831.                     nextchar = getc(yyin);
  832.                     lexstate = LEX_COMMENT;
  833.                 }
  834.                 else if (isdigit(nextchar) || (nextchar == '-'))
  835.                 {
  836.                     yytext[bufptr++] = nextchar;
  837.                     nextchar = getc(yyin);
  838.                     lexstate = LEX_INT;
  839.                 }
  840.                 else if (isalpha(nextchar))
  841.                 {
  842.                     yytext[bufptr++] = nextchar;
  843.                     nextchar = getc(yyin);
  844.                     lexstate = LEX_IDENT;
  845.                 }
  846.                 else if (nextchar == '"')
  847.                 {
  848.                     nextchar = getc(yyin);
  849.                     lexstate = LEX_STRING;
  850.                 }
  851.                 else if (ispunct(nextchar))
  852.                 {
  853.                     yytext[bufptr++] = nextchar;
  854.                     nextchar = getc(yyin);
  855.                     lexstate = LEX_PUNCT;
  856.                 }
  857.                 else if (nextchar == EOF)
  858.                 {
  859.                     lexstate = LEX_STOP;
  860.                 }
  861.                 else
  862.                 {
  863.                     wsprintf(szBuffer,
  864.                                   "unrecognized character '%c', line %d.\n",
  865.                                    nextchar, line_no);
  866.                     MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  867.                     yyerrexit();
  868.                     return(YYEXIT);
  869.                 }
  870.                 break;
  871.  
  872.             case LEX_INT:
  873.                 while (isdigit(nextchar))
  874.                 {
  875.                     yytext[bufptr++] = nextchar;
  876.                     nextchar = getc(yyin);
  877.                 }
  878.                 if (nextchar == '.')
  879.                 {
  880.                     yytext[bufptr++] = nextchar;
  881.                     nextchar = getc(yyin);
  882.                     lexstate = LEX_DEC;
  883.                 }
  884.                 else
  885.                 {
  886.                     yytext[bufptr] = 0;
  887.                     yylval.i = atoi(yytext);
  888.                     token = INTEGER;
  889.                     found_token = TRUE;
  890.                 }
  891.                 break;
  892.  
  893.             case LEX_DEC:
  894.                 while (isextdigit(nextchar))
  895.                 {
  896.                     yytext[bufptr++] = nextchar;
  897.                     nextchar = getc(yyin);
  898.                 }
  899.                 yytext[bufptr] = 0;
  900.                 sscanf(yytext,"%g",&yylval.f);
  901.                 token = REAL;
  902.                 found_token = TRUE;
  903.                 break;
  904.  
  905.             case LEX_IDENT:
  906.                 while (isalpha(nextchar) || isdigit(nextchar))
  907.                 {
  908.                     yytext[bufptr++] = nextchar;
  909.                     nextchar = getc(yyin);
  910.                 }
  911.                 yytext[bufptr] = 0;
  912.                 token = gettoken(yytext);
  913.                 found_token = TRUE;
  914.                 break;
  915.  
  916.             case LEX_STRING:
  917.                 while (nextchar != '"')
  918.                 {
  919.                     if (nextchar == '\n')
  920.                     {
  921.                         wsprintf(szBuffer,
  922.                                        "newline in string, line %d.\n",
  923.                                        line_no);
  924.                         MessageBox(NULL, szBuffer, "lf read_prog()", MB_OK | MB_ICONEXCLAMATION);
  925.                         return (YYEXIT);
  926.                     }
  927.                     yytext[bufptr++] = nextchar;
  928.                     nextchar = getc(yyin);
  929.                 }
  930.                 nextchar = getc(yyin); /* skip closing quote */
  931.                 yytext[bufptr] = 0;
  932.                 yylval.s = strdup(yytext);
  933.                 token = STRING;
  934.                 found_token = TRUE;
  935.                 break;
  936.  
  937.             case LEX_PUNCT:
  938.                 yytext[bufptr] = 0;
  939.                 token = gettoken(yytext);
  940.                 found_token = TRUE;
  941.                 break;
  942.  
  943.             case LEX_COMMENT:
  944.                 while (nextchar != '\n')
  945.                 {
  946.                     nextchar = getc(yyin);
  947.                 }
  948.                 lexstate = LEX_START;
  949.                 break;
  950.  
  951.             case LEX_STOP:
  952.                 token = 0;
  953.                 found_token = TRUE;
  954.                 first = TRUE;
  955.                 break;
  956.         }
  957.     }
  958.  
  959.     if (lexstate != LEX_STOP)
  960.     {
  961.         lexstate = LEX_START;
  962.     }
  963.     return(token);
  964. }
  965.